/**
 * Copyright(c): 2017 com.mjduan All rights reserved.
 * 项目名：learn-spring-web
 * 注意：未经作者允许，不得外传
 */
package com.mjduan.project.util.redis;

import java.util.concurrent.TimeUnit;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * @author mjduan@yahoo.com mjduan 2018-06-21 14:35
 * @version 1.0
 * @since 1.0
 */
@Configuration
public class RedisConfiguration {

//    @Bean(name = "jedisConnectionFactory")
//    public JedisConnectionFactory getJedisConnectionFactory() {
//        JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
//        jedisConnectionFactory.setPort(6379);
//        jedisConnectionFactory.setHostName("localhost");
//        return jedisConnectionFactory;
//    }

    @Bean(name = "StringRedisTemplate")
    public StringRedisTemplate getStringRedisTemplate(@Qualifier(value = "jedisConnectionFactory") JedisConnectionFactory jedisConnectionFactory) {
        StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
        stringRedisTemplate.setConnectionFactory(jedisConnectionFactory);
        return stringRedisTemplate;
    }

    @Bean(name = "RedisTemplate")
    public RedisTemplate getRedisTemplate(@Qualifier(value = "jedisConnectionFactory") JedisConnectionFactory jedisConnectionFactory) {
        RedisTemplate redisTemplate = new RedisTemplate();
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new CustomSerializer());
        //redisTemplate.setDefaultSerializer(new CustomSerializer());
        redisTemplate.setConnectionFactory(jedisConnectionFactory);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

    @Bean(name = "CustomRedisTemplate")
    public CustomRedisTemplate getCustomRedisTemplate(@Qualifier(value = "RedisTemplate") RedisTemplate redisTemplate) {
        return new CustomRedisTemplate(redisTemplate);
    }

    private static class CustomSerializer implements RedisSerializer {

        @Override
        public byte[] serialize(Object obj) throws SerializationException {
            return JSON.toJSONString(obj).getBytes();
        }

        @Override
        public Object deserialize(byte[] bytes) throws SerializationException {
            return null != bytes ? JSON.parseObject(bytes, JSONObject.class) : null;
        }
    }

    public class CustomRedisTemplate {
        private RedisTemplate redisTemplate;

        public CustomRedisTemplate(RedisTemplate redisTemplate) {
            this.redisTemplate = redisTemplate;
        }

        public <T> T get(String key, Class<T> clazz) {
            JSONObject jsonObject = (JSONObject) redisTemplate.boundValueOps(key).get();
            return null != jsonObject ? jsonObject.toJavaObject(clazz) : null;
        }

        public void set(String key, Object value) {
            redisTemplate.boundValueOps(key).set(value);
        }

        public void set(String key, Object value, long time, TimeUnit timeUnit) {
            redisTemplate.boundValueOps(key).set(value, time, timeUnit);
        }
    }
}
